package com.qf.mpswaggershiro.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qf.mpswaggershiro.product.entity.Category;
import com.qf.mpswaggershiro.product.mapper.CategoryMapper;
import com.qf.mpswaggershiro.product.service.ICategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.mpswaggershiro.product.entity.Product;
import com.qf.mpswaggershiro.product.entity.ProductImg;
import com.qf.mpswaggershiro.product.mapper.ProductMapper;
import com.qf.mpswaggershiro.product.service.IProductImgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品分类 服务实现类
 * </p>
 *
 * @author cui
 * @since 2023-02-14
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements ICategoryService {
    @Autowired
ProductMapper productDao;
@Autowired
    IProductImgService productImgService;

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Category> categoryList() {

        //查询所有1级分类信息
        List<Category> firstCategoryList = list(new QueryWrapper<Category>().eq("parent_id", 0));
        //遍历所有查询的一级分类，填充二级分类
        for (Category category : firstCategoryList) {
            //获取当前一级分类ID
            Integer categoryId = category.getCategoryId();
            //查询当前ID下有那些二级分类
            List<Category> secondCategoryList = list(new QueryWrapper<Category>().eq("parent_id", categoryId));

            //遍历secondCategoryList 为每个二级分类对象填充三级分类 数据
            for (Category category1 : secondCategoryList) {
                //获取二级分类Id
                Integer secId = category1.getCategoryId();
                List<Category> thirdCategoryList = list(new QueryWrapper<Category>().eq("parent_id", secId));

                //把三级分类设置到二级分类中
                category1.setCategories(thirdCategoryList);
            }

            //把查询出来的二级分类，设置到一级分类对象中
            category.setCategories(secondCategoryList);
        }

        return firstCategoryList;
    }




@Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Category> categoryListBySql() {

    CategoryMapper mapper = this.getBaseMapper();


    return mapper.listCategoryList();
    }

    /**
     * 首页的分类推荐商品信息
     * @return
     */
    //-------------------------------------------------------------------------------------------------
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Category> recommendsList() {
        //查询一级列表的所有数据
        QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
        categoryQueryWrapper.eq("parent_id",0);
        List<Category> oneList = list(categoryQueryWrapper);

        for (Category category : oneList) {
            //查询销量前六的
            QueryWrapper<Product> productQueryWrapper = new QueryWrapper<>();
            //先分页   排序
            Page<Product> productPage = new Page<>(1, 6);
            //根据销量 倒序排名
            productQueryWrapper.orderByDesc("sold_num");
            productQueryWrapper.eq("root_category_id",category.getCategoryId());

            //执行分页查询 第二个参数是条件
            Page<Product> page = productDao.selectPage(productPage, productQueryWrapper);
            //执行完分页方法后，获取分页对象具有所以分页相关信息（当前页的数据，总条数）
            List<Product> records = page.getRecords();

            if (records!=null&&records.size()>0){
                QueryWrapper<ProductImg> productImgQueryWrapper = new QueryWrapper<>();
                //固定写法.stream().map   把list<object>---->list<string>
                List<String> idList = records.stream().map(Product::getProductId).collect(Collectors.toList());
                //找到item_id中和分页查询表中相同的id
                productImgQueryWrapper.in("item_id",idList);
                List<ProductImg> list = productImgService.list(productImgQueryWrapper);

                //将原本list中的id和img数据  放入map中  变成key-->id  value-->img
                Map<String, List<ProductImg>> listMap = list.stream().collect(Collectors.groupingBy(ProductImg::getItemId));

                records.forEach(new Consumer<Product>() {
                    @Override
                    public void accept(Product product) {
                        List<ProductImg> productImgs = listMap.get(product.getProductId());
                        if (productImgs==null){
                           productImgs = new ArrayList<>();
                        }
                        product.setImgs(productImgs);
                    }
                });

            }
            category.setProducts(records);
        }

        return oneList;
    }

    /**
     * 把表中的东西都放到java中   精简版
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Category> categoryListRecursive() {
    // 查询全表的分类信息
    List<Category> all = list();
    // 通过stream 的filter方法，获取到 顶级分类数据
        //把list对象转换成stream流对象 过滤（满足要求为true留下来，不满足为false踢出去）.最后在转回list
        List<Category> firstList = all.stream().filter(category -> category.getParentId().equals(0)).collect(Collectors.toList());


        // 给当前的分类信息填充下级分类信息
        populateChild(firstList,all);

    return firstList;
    }

    /**
     * 给传入的 list中的所有分类对象填充下级分类   （精简版的递归）
     * @param list  传入的分类的list
     * @param all   全部分类数据
     */
    private void populateChild(List<Category> list, List<Category> all) {
        // 给 当前分类list中的所有分类对象填充下属的二级分类信息
        for (Category category : list) {
            final Integer categoryId = category.getCategoryId();
            // 过滤all，保留 parentId= categoryId 的数据，就是当前需要的下级分类数据
            final List<Category> child = all.stream().filter(c -> c.getParentId().equals(categoryId)).collect(Collectors.toList());

            if (child != null && child.size() > 0) {
                populateChild(child, all);
            }

            // 挂载二级分类
            category.setCategories(child);
        }
    }

    /**
     *
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Category> categoryListRecursiveBetter() {
        //查询全表分类信息
        List<Category> all = list();

        //创建一个Map,key=parentId   value=list<category>
        Map<Integer, List<Category>> pIdMap = all.stream().collect(Collectors.groupingBy(new Function<Category, Integer>() {
            @Override
            public Integer apply(Category category) {
                //按照ParentId进行分组
                return category.getParentId();
            }


        }));
        // 获取顶级分类List
        List<Category> first = pIdMap.get(0);
// 给当前分类List填充下级分类数据
        pupulateBetter(first,pIdMap);

        return first;
    }

    private void pupulateBetter(List<Category> list, Map<Integer, List<Category>> pIdMap) {
        for (Category category : list) {
            Integer cId = category.getCategoryId();
            // 获取当前cId下属分类信息
            List<Category> child = pIdMap.get(cId);

            if (child!= null && child.size() > 0) {
                pupulateBetter(child,pIdMap);
                // 填充下属分类
                category.setCategories(child);
            }else {
                // 当没有下级分类数据时，创建一个长度为0的list，避免遍历数据时出现空指针异常；也确保前端拿到的json中，是[]
                category.setCategories(new ArrayList<>());
            }

        }
    }
}
